//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "FS2_Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TmyForm *myForm;
//---------------------------------------------------------------------------
__fastcall TmyForm::TmyForm(TComponent* Owner)
  : TForm(Owner)
{
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::OpenBinaryTextData1Click(TObject *Sender)
{
  char buf[256],
       *p;
  long fsize;
  LONG valu,
       cmpv;
  LONG cIndex;
  WORD pointer;
  FILE *tf;

  LONG offset;
  LONG lpPosi;
  int  count;

  Open1->Title      = "Open ROM File";
  Open1->Filter     = "SNES ROM | *.s*c; *.fig;";
  Open1->InitialDir = cur_dir;
  //
  if ( Open1->Execute( ) )
  { // Create Dump directory!
    getcwd( dirc, MAXPATH );
    strcat( dirc, "\\Dumps" );
    mkdir( dirc );

    //
    strcpy(romf, Open1->FileName.c_str( ) );
    tf = fopen( romf, "rb" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open file!");
      return;
    }
    //
    if ( rom.data ) rom.data -= rom.Header;
    _free( rom.data );
    rom.data = (BYTE *)malloc( rom.Length = FileSize( tf ) );
    //
    if ( !rom.data ){
      fclose( tf );
      ShowMessage( "Fatal Error: Could not allocate needed memory!" );
      Close( );
    }

    // Check for dumb header
    rom.Header = ( rom.Length & 0x0200 );

    // Read in the data
    fread( rom.data, 1, rom.Length, tf );
    fclose( tf );
    //---------------------------------//
    // Make sure it's Light Fanstasy 2 //
    //---------------------------------//
    if ( strncmp( &rom.data[0xFFC0], "FARLANDSTORY2", 13 ) ){
      ShowMessage("Error: This is not the ROM used.\n"
                  "Please load the correct ROM."
                 );
      _free( rom.data );
      return;
    }
    //
    // Enable Text file
    LoadDataFile->Enabled = true;

    // Try to open a Script File
    LoadDataFileClick( Sender );
    //
    if ( cmForm->bList->Items->Count <= 0 ) return;
    cmForm->bList->ItemIndex = 0;
    if ( cmForm->Visible ) cmForm->bList->SetFocus( );
//    bListClick( NULL );
    //
    iCanDraw = true;
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::SaveTextFile1Click(TObject *Sender)
{
  TxtForm->TDMemo->Lines->SaveToFile( AnsiString( txtf ) );
  ShowMessage( "\"" + AnsiString( ExtractFileName(txtf) ) + "\" was saved successfully!" );
  TxtForm->TDMemo->Modified = false;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Exit1Click(TObject *Sender)
{
  Close( );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::bListClick(TObject *Sender)
{
  FILE *df;
  WORD cmpv;
  long valu;
  char buf[256],
       *p;

  if ( !ram || !rom.data ) return;

  for ( int i = 0; i < cmForm->bList->Items->Count; i++ )
  { //
    if ( cmForm->bList->Selected[ i ] )
    { //
      txt.ptr_posi = Snes2Pc( lpTxtBlocks[ i ] );
      txt.Max_ptrs = 0;//(lpPointSize[ i ] - lpTxtBlocks[ i ]) / 3;
      txt.posi     = i;

      txt.Max_ptrs = GetTextPointers( txt.ptr_posi );
      // Any errors?
      if ( txt.Max_ptrs == -1 ){
        ShowMessage( "Scripting Read Error: Pointers could not be loaded." );
        return;
      }

      // File the list box with data
      cmForm->pList->Clear( );
      for ( int c = 0; c < txt.Max_ptrs; c++ )
      {
        sprintf( buf, "String# %-5d", c );
        cmForm->pList->Items->Add( AnsiString( buf ) );
        //
//        lpTxtPoints[ c ] = LGET( rom.data, Snes2Pc( txt.ptr_posi + (c * 3) ) ) & 0xFFFFFF;
      }
      //------------------------//
      // Get new text file data //
      //------------------------//
//      sprintf( buf, "%s/Block_%02d.txt", dirc, i );
//      sprintf( buf, "%s\\%08X.txt", dirc, txt.ptr_posi );
      sprintf( buf, "%s\\%08X.txt", dirc, lpTxtBlocks[ i ] );
//      strcpy( txtf, buf );
      if ( FileExists( AnsiString( txtf ) ) )
      { //
        if ( TxtForm->TDMemo->Modified ){
           int k = Application->MessageBox(
             "Current data not saved. Do you wish to save it?",
             "File Modified...",
             MB_ICONQUESTION + MB_YESNO
           );
           // If yes, save the file
           if ( k == ID_YES )
             SaveTextFile1Click( NULL );
        }
      }

      // Load new data
      strcpy( txtf, buf );
      if ( FileExists( AnsiString( txtf ) ) )
        TxtForm->TDMemo->Lines->LoadFromFile( AnsiString(txtf) );
      else
      { //
        if ( !FileExists( AnsiString( buf ) ) )
        { // Create the dump Data
          df = fopen( buf, "wt" );
          if ( df )
          { //
            fprintf( df, "// Do not erase these: \n// .STRING #\n// .ENDS\n\n\n" );
            for ( int c = 0; c < txt.Max_ptrs; c++ )
              fprintf( df, ".STRING %d\n\n.ENDS\n\n\n\n", c );

            // Close the file
            fclose( df );
            // Now load the data
            if ( FileExists( AnsiString( buf ) ) )
              TxtForm->TDMemo->Lines->LoadFromFile( AnsiString( buf ) );
          }// END IF - df
        }// END IF - File exist
      }

      //
      txt.posi         = i;
      cmForm->pList->ItemIndex = 0;
      cur_str          = 0;

      cmForm->pList->Hint      = IntToStr( cmForm->pList->Items->Count ) + " item(s)";
      pListClick( NULL );
      if ( cmForm->Visible ) cmForm->bList->SetFocus( );
      TxtForm->TDMemo->Modified = false;
      break;
    }// NEXT
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::LoadDataFileClick(TObject *Sender)
{
  LONG x,y,z;
  int  cpos;
  CODE *tcode = NULL;
  char buf[560],
       cuf[560],
       arg1[32],
       arg2[32],
       var[16],
      *p;
  FILE *tf,
       *df;

  Open1->Title    = "Open Text Block Data File";
  Open1->Filter   = "Font Format File | *.txt";
  Open1->FileName = "";
  //
  if ( Open1->Execute( ) )
  { //
    tf = fopen( Open1->FileName.c_str( ), "rt" );
    if ( !tf ){
      ShowMessage("Fatal Error: Could not open FONT file!");
      return;
    }

    iCanDraw       = false;
    memset(buf, 0, 256);
    cmForm->bList->Clear( );
    cpos = 0;

    // get the format data
    while( fgets( buf, 256, tf ) )
    { //----------------------//
      // Textbox color data   //
      //----------------------//
      if ( !strncmpi(buf, ".textbox", 8) )
      { //
        sscanf( buf, "%s %s", &cuf, &arg1 );
        // Get the color
        if ( strstr( buf, ".color.blue") ) Blue1->Checked   = true;
        if ( strstr( buf, ".color.green")) Green1->Checked = true;
        if ( strstr( buf, ".color.red")  ) Red1->Checked   = true;
        // Get the color type
        if ( strstr( buf, ".solid" ) )     Solid1->Checked = true;
        if ( strstr( buf, ".gradient"))    Gradient1->Checked = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".Font", 5) )
      {
        sscanf( buf, "%s %X", &cuf, &map.lpFontOffset );
      }
      //
      if ( !strncmpi(buf, ".TransText", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "SHOW" ) ){
          DTT->Checked = false;
          DTTClick( Sender );
        }
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".CONTROLCODES", 13) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "HIDE" ) ) HideCodes->Checked = false; else HideCodes->Checked = true;
        HideCodesClick( Sender );
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".VWF", 4) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "ON" ) ) UseVWFRoutine1->Checked = false; else UseVWFRoutine1->Checked = true;
        UseVWFRoutine1Click( Sender );
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".TextWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) TxtForm->Visible = false; else TxtForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".HexWindow", 10) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) HexForm->Visible = false; else HexForm->Visible = true;
      }
      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".KanaWindow", 11) )
      {
        sscanf( buf, "%s %s", &cuf, &cuf );
        if ( !strcmpi( cuf, "hide" ) ) KanaForm->Visible = false; else KanaForm->Visible = true;
      }

      //----------------------//
      //                      //
      //----------------------//
      if ( !strncmpi(buf, ".FORMAT", 7) )
      { // goto _ReadGood;
        sscanf( buf, "%s   %d    %d  %d  %d   %d   %d %d %d %d",
                &buf[128],
                &map.cpl,
                &map.height,
                &map.width,
                &map.bpp,
                &map.inc,
                &map.set[0], &map.set[1],
                &map.set[2], &map.set[3]
              );
        //
        map.cpl *= map.inc;
      }

      //
      if ( !strncmpi(buf, ".BLOCK", 6) )
      { //
        x = y = z = 0;
        sscanf( buf, "%s %X %X", &cuf, &x, &y );
        //
        sprintf( buf, "Block %X", x );
        //
        lpTxtBlocks[ cpos ] = x;
        lpTxtMaxPos[ cpos ] = y;
        lpTextStart[ cpos ] = 0;
        lpTxtPoints[ cpos ] = 0;
        cpos++;
        //
        cmForm->bList->Items->Add( buf );
      }
      //---------------------------------------//
      // Check for color able index assignment //
      //---------------------------------------//
      if ( !strncmpi( buf, ".COLORTABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL=", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          {
            p = strchr( buf, '=' );
            if ( !p ) continue;
            *p = ' ';
            sscanf( buf, "%s %s", &cuf, &arg1 );
            //
            if ( !y ){
              // DUALS
              for ( int c = 0; c < 0x10000; c++ )
                if ( duals[c].type ) duals[c].color = GetIndex( arg1 );
            } else {
              // CODES
              for ( int c = 0; c < 0x00100; c++ )
                if ( codes[c].type ) codes[c].color = GetIndex( arg1 );
            }
          }
          else
          //----------------------------------//
          // Standard colors for table values //
          //----------------------------------//
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            sscanf( buf, "%X %s", &x, &arg1 );
            //
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->color = GetIndex( arg1 );
          }
          else
          if ( strstr( buf, ".ENDCOLOR" ) )
            break;
          // end if
        }
      }
      //-------------------------//
      // Load up table file data //
      //-------------------------//
      if ( !strncmpi( buf, ".TABLE", 6 ) )
      { //
        while( fgets( buf, 256, tf ) )
        { // Load the text value
          if ( !(x = strncmpi( buf, ".NULL ", 6)) || !(y = strncmpi( buf, ".NULL16", 7)) )
          { //
            sscanf( buf, "%s %s %s %s", &cuf, &arg1, &cuf, &arg2 );
            //
            int  min = GetIndex( arg1 ),
                 max = GetIndex( arg2 );
            //
            if ( min > max ){
              x   = min;
              min = max;
              max = x;
            }
            //
            for ( int c = min; c <= max; c++ )
            { //
              tcode = ( (!x) ? &codes[c] : &duals[c] );
              //
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", c );
              tcode->type = 1;  // Make this a NULL code
            }

          }
          else
          if ( p = strchr( buf, '=' ) )
          { //
            *p = ' ';
            z = (LONG)p - (LONG)buf;
            //
            memset( cuf, 0, 256 );
            sscanf( buf, "%X %s", &x, &cuf );
            if ( z > 2 )
              tcode = &duals[x];
            else
              tcode = &codes[x];
            //
            tcode->length = strlen( cuf );
            memset( buf, 0, 256 );
            // Format string and get length
            if ( strstr( cuf, "\\x" ) )
            { //
              tcode->length = 0;
              for ( int c = 0; c < strlen( cuf ); c++ )
              { //
                if ( cuf[ c ] == '\\' && cuf[ c + 1 ] == 'x' )
                { //
                  c += 2;
                  memset( var, 0, 16 );
                  var[ 0 ] = cuf[ c++ ];
                  var[ 1 ] = cuf[ c++ ];
                  //
                  buf[ tcode->length++ ] = strtoul( var, NULL, 16 );
                }
                else
                  buf[ tcode->length++ ] = cuf[ c ];
                //
              }
              //
              memset( cuf, 0, 256 );
              memcpy( cuf, buf, tcode->length + 1 );
            }
            //
            // Set the End of text BYTE
//            cuf[ tcode->length ] = 0xFF;
            tcode->text = (BYTE *)malloc( tcode->length + 1 );
            //
            if ( !tcode->text ){
              ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
              fcloseall( ); Close( ); return;
            }
            //
            memcpy( tcode->text, cuf, tcode->length + 1 );
            //----------------------//
            // This means it's NULL //
            //----------------------//
            if ( !tcode->length )
            { //
              _free( tcode->text );
              tcode->text = (BYTE *)malloc( 6 );
              if ( !tcode->text ){
                ShowMessage( "Error: Program outof memory. 'TABLE DATA Load'. " );
                fcloseall( ); Close( ); return;
              }
              //
              sprintf( tcode->text, "[$%02X]", x );
              tcode->type = 1;  // Make this a NULL code
            }
          }
          else
          if ( strstr( buf, ".ENDTABLE" ) )
            break;
          // end if
        }
      }
    }
    // Load all block data
    fclose( tf );
    iCanDraw = true;
    //
    myForm->Caption = "Script Editor: Farland Story 2 - [ " + ExtractFileName( Open1->FileName ) + " ]";
     // Init the first block
    cmForm->bList->ItemIndex = 0;
    cmForm->bList->Hint = IntToStr( cmForm->bList->Items->Count ) + " item(s)";
    bListClick( NULL );
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormCreate(TObject *Sender)
{
  WORD *VRAM;

  Vga = new Graphics::TBitmap;
  //
  if ( !Vga ){
    ShowMessage("Fatal Error: Could not acquire Video Pointer." );
    Close( );
    return;
  }

  // Starting directory
  getcwd( cur_dir, MAXPATH );

  Vga->Width       = Video->Width;
  Vga->Height      = Video->Height;
  Vga->PixelFormat = pf16bit;
  //
  txt.posi  = 0;
  txt.index = 0;
  //
  ScrBuf         = (WORD *)malloc( (Vga->Width * Vga->Height) << 2 );
  textbox[0].pic = (WORD *)malloc( (0x39000 << 2) );
  textbox[1].pic = (WORD *)malloc( (0x39000 << 2) );
  //
  lpTxtBlocks = (LONG *)malloc( TEXT_ENTRIES * sizeof(LONG) );
  lpTxtPoints = (LONG *)malloc( TEXT_ENTRIES * sizeof(LONG) );
  lpTextStart = (LONG *)malloc( TEXT_ENTRIES * sizeof(LONG) );
  lpTxtMaxPos = (LONG *)malloc( TEXT_ENTRIES * sizeof(LONG) );
  //
  ram  = (BYTE *)malloc( 0x20000 );
  EStr = (BYTE *)malloc( 0x20000 );
  if ( !ram || !ScrBuf || !textbox[0].pic ||
       !textbox[1].pic || !EStr ||
       !lpTxtBlocks || !lpTxtPoints ||
       !lpTextStart || !lpTxtMaxPos
  ){
    ShowMessage("Fatal Error: Could not allocate memory!" );
    myForm->Close( );
    return;
  }

  //
  memsetw( ScrBuf, 0x0000, Vga->Width * Vga->Height );
  memset( ram, 0, 0x20000 );
  textbox[0].height = 0x0300;
  textbox[1].height = 0x0300;
  //
  WinX = myForm->ClientWidth;
  WinY = myForm->ClientHeight;
  // Assign default colors to codes
  for ( int c = 0; c < 0x10000; c++ )
    codes[(c / 256)].color =
    duals[ c ].color       = 15;
  //
  for ( int y = 0; y < Vga->Height; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y ];
      memset( VRAM, 0, Vga->Width << 1);
  }
  //
  Video->Canvas->StretchDraw( Video->ClientRect, Vga );

  iCanDraw = false;
  isActive = true;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::FormClose(TObject *Sender, TCloseAction &Action)
{
  int  k;
  
  if ( TxtForm && TxtForm->TDMemo->Modified )
  { //
    k = Application->MessageBox(
      "TEXT data not saved. Do you wish to save it?",
      "TEXT File Modified...",
      MB_ICONQUESTION + MB_YESNO
    );
    // If yes, save the file
    if ( k == ID_YES )
      SaveTextFile1Click( NULL );
  }
  //
  if ( rom.Modified )
  { //
    k = Application->MessageBox(
      "ROM data modified. Do you wish to save changes?",
      "ROM File Modified...",
      MB_ICONQUESTION + MB_YESNO
    );
    // If yes, save the file
    if ( k == ID_YES )
      SaveRomFile1Click( NULL );
  }
  //
  rom.data - rom.Header;
  _free( rom.data );
  _free( ram );
  _free( EStr );
  _free( ScrBuf );
  _free( textbox[0].pic );
  _free( textbox[1].pic );
  //
  _free( lpTxtBlocks );
  _free( lpTxtPoints );
  _free( lpTxtMaxPos );
  _free( lpTextStart );
  //
  for ( int c = 0; c < 0x10000; c++ )
    _free( duals[c].text );

  isActive = false;

  if ( Vga ) delete Vga;
  if ( HexForm && HexForm->PIC ) delete HexForm->PIC;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::DrawText( int  skip, int height, int width )
{
  #define StartX     0
  #define StartY     0
  #define MASK_COLOR 0x11

  #define BLACK      0x00
  #define BLUE       0x01
  #define GREEN      0x02
  #define TEAL       0x03
  #define RED        0x04
  #define PURPLE     0x05
  #define BROWN      0x06
  #define GRAY       0x07

  #define CHARCOAL   0x08
  #define LtBLUE     0x09
  #define LtGREEN    0x0A
  #define LtTEAL     0x0B
  #define LtRED      0x0C
  #define LtPURPLE   0x0D
  #define YELLOW     0x0E
  #define WHITE      0x0F


  #define NONTEXT    0x0A
  #define NONTEXT2   0x0C
  #define NONTEXT3   0x04
  #define NONTEXT4   0x09
  #define NONTEXT5   0x0E
  #define DICTIONARY 0x2B

  LONG base_posi;
  LONG rom_posi;
  LONG tilep;
  LONG cpOffset;

  char buf[256];
  WORD *VRAM;
  static TBOX *myBox;
  WORD val[4];
  BYTE *TEMP    = NULL,
       COLR,
       TCOLR,
       BITS = 0,
       cwFirst = 0,
       BUFR[0x100],
       TILE[16][16],
       flag = 0,
       VWF;

  // Make sure we can do this!
  if ( !rom.data || !ram || !iCanDraw ) return;

  if ( !map.cpl ){
    map.cpl    = 18;
    map.height = 16;
    map.width  = 16;
    map.bpp    = 1;
    map.inc    = 16;
    map.set[0] = 0;
    map.set[1] = 1;
    map.set[2] = 2;
    map.set[3] = 3;
    map.cpl *= 8;
    //
    return;
  }

  if ( !skip )
  { // Get the Text pointer and display the text!
    myBox      = &textbox[ (int)DTT->Checked ];
    memsetw( myBox->pic, 0, 0x39000 );
    memset( &men, 0, sizeof(TMEN) );
    //
    txt.tColor = 15;
    txt.data   = 0;
    men.Ypos   = 0;
    men.Xpos   = 0;
    // Select which text box to use
    txt.xpos   = StartX;
    txt.ypos   = StartY;
    if ( !DTT->Checked ) memsetw( ScrBuf, 0, (Vga->Width * Vga->Height) );
    //----------------------------//
    // Check to see if we use the //
    // ROM or the buffer          //
    //----------------------------//
    if ( DTT->Checked )
    { //
      txt.TextBuf  = EStr;
      men.Xdim     = 29;
      myBox->width = men.Xdim << 3;
      flag         = 1;
    }
    else
    { //
      {
        txt.pntr    = lpTxtPoints[ txt.ptr_index ];
        txt.TextBuf = &rom.data[ Snes2Pc( txt.pntr ) ];
      }
//      else
      {
//        txt.TextBuf = "NON-TEXT DATA\xff\xff";
//        flag        = 1;
//        skip        = 1;
      }
      //
      map.cpl       = (29 << 3);
      men.Xdim      = map.cpl >> 3;
      myBox->width  = men.Xdim << 3;
    }
    //
    if ( !DTT->Checked ){
      // Draw the hex data
//      HexForm->DrawHex( txt.TextBuf, flag );
      // Dump the text to the string viewer
//      KanaForm->ShowText( txt.TextBuf, flag );
    }
  }

  //------------------------------------//
  // Display the text data              //
  //------------------------------------//
  while( txt.data != 0xFFFF )
  { //
    BITS         = 0;
    txt.data     = *(WORD *)&txt.TextBuf[0];
    txt.TextBuf += 1;

    //----------------//
    // End Text Write //
    //----------------//
    if ( txt.data == 0xFFFF )
    {
      _BREAK_TEXT_:
      txt.data = 0x0000;
      if ( skip && !flag ) return;
      break;
    }

    //-------------//
    // Control Codes    //
    //-------------//
    if ( (txt.data & 0xF000) == 0x8000 )
    { //
      txt.TextBuf += 1;
      _NoShowCode:
      switch( txt.data )
      { // End Text
        case 0x8000: txt.data = 0xFFFF; goto _BREAK_TEXT_;
        // Newline
        case 0x8001: _HideOn_:
                     txt.ypos += 0x10;
                     txt.xpos  = StartX;
                     continue;
        // 8x16 text
        case 0x8006: sprintf( buf, "[Text8x16]\xff\xff" ); break;
        // 16x16 text
        case 0x8007: sprintf( buf, "[Text16x16]\xff\xff" ); break;
        // Keypress
        case 0x800C: sprintf( buf, "[Key]\x01\x80\xff\xff" );
                     if ( HideCodes->Checked ) goto _HideOn_;
                     break;
        //
//        case 0x800D: sprintf( buf, "[Key]\xff\xff" ); break;
        // Clear Screen
        case 0x800F: sprintf( buf, "[ClrScr]\xff\xff" ); break;
        //--------------------------------
        default    : sprintf( buf, "[$%04X]\xff\xff", txt.data ); break;
      }

      //
      if ( !BITS )
      { //
        TEMP        = (BYTE *)txt.TextBuf;
        COLR        = txt.tColor;
        txt.tColor  = YELLOW;

        txt.TextBuf = buf;
        //
        if ( !HideCodes->Checked )
          DrawText( true, 16, 8 );
        //
        txt.tColor  = COLR;
        txt.TextBuf = TEMP;
        TEMP        = NULL;
        txt.data    = 0;
        continue;
      }
    } //


    //--------------------//
    // Control Code stuff //
    //--------------------//
    if ( skip )
    { //
      txt.data = (txt.data & 0x00FF);
    }


    //-----------------------------//
    // Font size testing done here //
    //-----------------------------//
    if ( !skip && !DTT->Checked )
    { // Get to the next WORD
      txt.TextBuf += 1;
      // Display the text
      txt.tpos  = ((txt.data & 0xFFFF) * 0x20);
      memcpy( BUFR, &rom.data[ 0x41000 + txt.tpos ], 0x20 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ x << 4 ], (BUFR[ x + 0 ] << 8) + BUFR[ x + 16 ], 16 );
      //
    }
    else
    //--------------------------//
    // My font used by the game //
    //--------------------------//    11000000 -> 00011000
    if ( !skip && DTT->Checked )
    { //
      memcpy( BUFR, &FONT16x16[ (txt.data & 0xFF) << 5 ], 0x20 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ (x * width) ], (BUFR[ x + 0] << 8) + BUFR[x + 16], 16 );
      //
    }
    else
    //--------------------------//
    // 8x16 for control codes   //
    //--------------------------//
    if ( skip )
    { //
      memcpy( BUFR, &FONT8x16[ (txt.data & 0xFF) << 4 ], 0x10 );
      memset( txt.tile, 0, 256 );
      // Convert the tile data
      int x = -1;
      while( ++x < 16 )
        Dec2Bin( &txt.tile[ x << 3 ], BUFR[ x ], 8 );
      //
    }

    //---------------//
    // DMA to Vram   //
    //---------------//
    VWF       = 0;
    txt.ypos %= myBox->height;
    //
    for ( int y = 0; y < height; y++ )
    { //
      for ( int x = 0; x < width; x++ )
      { //
        if ( txt.tile[ (y * width) + x ] )
        { // Add pixel
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ]     = DOS565[ txt.tColor ];
          // Add Shadow on the side
          myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 1) ]     = DOS565[ MASK_COLOR ];
          // Add Shadow on the bottom + side
//          myBox->pic[ ((txt.ypos + y + 1) * myBox->width) + (txt.xpos + x + 1) ] = DOS565[ MASK_COLOR ];
          // For VWF routine
          if ( x > VWF ) VWF = x;
          // For some reason single pixel
          // fonts don't record a value
          if ( !VWF ) VWF = 1;
        }
        else
        { //
          if ( myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] != DOS565[ MASK_COLOR ] )
            myBox->pic[ ((txt.ypos + y) * myBox->width) + (txt.xpos + x + 0) ] = DOS565[ 0 ];
        }
        //
      }
    }// NEXT y

    //
    if ( UseVWFRoutine1->Checked || skip )
    { //
      if ( !VWF ) VWF = 4;
      txt.xpos += VWF + 2;
    }
    else
//      txt.xpos += ( (width == map.width) ? map.inc : 5 );
      txt.xpos += width;
    //
    // Check Width boundaries for NON-English
    if ( !DTT->Checked && txt.xpos >= (map.cpl-16) )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
    }

    // Check Width boundaries for NON-English
    if ( DTT->Checked && txt.xpos >= ((men.Xdim << 3) - 16) )
    { //
      txt.xpos  = StartX;
      txt.ypos += 0x10;
    }
  }

  // Build Map, Draw the MenuMap, masking enabled
//  men.Ydim = ( men.Ydim > (Vga->Height>>3) ? (Vga->Height>>3) : men.Ydim );
  men.Ydim                = 14;
  men.menu[0][0]          = 1;
  men.menu[0][men.Xdim-1] = 3;
  memset( &men.menu[0][1], 2, men.Xdim - 2 );
  //
  men.menu[men.Ydim-1][0]        = 6;
  men.menu[men.Ydim-1][men.Xdim-1] = 8;
  memset( &men.menu[men.Ydim-1][1], 7, men.Xdim - 2 );
  //
  for ( int y = 1; y < men.Ydim-1; y++ )
  { //
    men.menu[y][0]        = 4;
    men.menu[y][men.Xdim-1] = 5;
  }
  //-----------------------------//
  // Which box to draw & display //
  //-----------------------------//
  if ( !DTT->Checked )
    MenuMap( &ScrBuf[(0x08 * Vga->Width) + 8], &men, Vga->Width, 0 );
  else
    MenuMap( &ScrBuf[(0x88 * Vga->Width) + 8], &men, Vga->Width, 0 );
  //
  myBox->Xpos = (DTT->Checked ? 0x88 : 0x08);
  //
  int  ypos = (DTT->Checked ? 0x88 : 0x08);
  for ( int y = 0; y < ((men.Ydim+0) << 3); y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ y + myBox->Xpos ];
     memcpyw( VRAM, &ScrBuf[ (y + ypos) * Vga->Width ], Vga->Width, 0 );
  }// NEXT y
  //
  myBox->Xpos = (DTT->Checked ? 0x90 : 0x10);
  //
  for ( int y = 0; y < 96; y++ )
  { //
    (void *)VRAM = Vga->ScanLine[ (y + myBox->Xpos) ];
     // Draw the Text data
     memcpyw( &VRAM[16], &myBox->pic[ ((y + myBox->Ypos) * myBox->width) ], myBox->width, 2 );
  }// NEXT y

  Video->Canvas->StretchDraw( Video->ClientRect, Vga );
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::VideoPaint(TObject *Sender)
{

  if ( rom.data )
//  Video->Canvas->StretchDraw( Video->ClientRect, Vga );
    Video->Canvas->StretchDraw( Video->ClientRect, Vga );

}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::pListClick(TObject *Sender)
{
  #define LINE_BREAK 0x8001
  #define TEXT_BREAK 0xFFFF
  #define STRING_END 0x00

  long valu,
       pos;
  WORD inPosi,
       sLen;
  char buf[256],
       tuf[256];
  char conv[16],
       flag,
       c_test,
       *p1,
       *p2;
  char *codes [ ] =
  {
    "KEY"     , "\xF0",
//    "PAUSE"   , "\xF1",  // args: 1 BYTE
    "SFX"     , "\xF3",
    "NAME"    , "\xF4",
    "MEM_NUM" , "\xF5",
    "MEM_TEXT", "\xF6",
    "FADEIN"  , "\xF7",
    "FADEOUT" , "\xF8",
//    "YES/NO"  , "\xF9",  // args: 2 WORDS
    "TEXTBOX" , "\xFB",
    "CLRWIN"  , "\xFC",
    "NEWLINE" , "\xFD",
    "\0"      , "\x00"
  };


  if ( !ram || !rom.data ) return;
  //
  for ( int k = 0; k < cmForm->pList->Items->Count; k++ )
  { //
    if ( cmForm->pList->Selected[ k ] )
    { //---------------------//
      // Draw the Kana First //
      //---------------------//
      // reset scrolling positions
      if ( !TxtForm->Active ) {
        textbox[0].Ypos = 0;
        textbox[1].Ypos = 0;
      }
      //
      DTT->Checked    = false;
      txt.ptr_index   = k;
      DrawText( false, map.height, map.width );
      // Get to the string Location
      sprintf( buf, ".STRING %d", k );
      //
      KanaForm->Caption = "Kana Text: String #" + IntToStr( k );
      // Disable the Main window
      Find1->FindText  = AnsiString( buf );

      if ( (LONG)Sender == 1 )
        Find1Find( (TObject *)1 );
      else
        Find1Find( NULL );

      txt.ptr_index = k;
      //------------------------------//
      // Build translated text string //
      //------------------------------//
      if ( indexLine != -1 )
      { // Clear the buffer
        // copy text to temp buffer
        TxtForm->Memo1->Clear( );
        valu = 0;
        //
        while( Trim( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] ) != ".ENDS" )
          TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu++ ] );
        //
        TxtForm->Memo1->Lines->Add( TxtForm->TDMemo->Lines->Strings[ indexLine + valu ] );
        //
        memset( EStr, 0, sizeof( EStr ) );
        inPosi = 0;
        //-------------------//
        //                   //
        //-------------------//
//        for ( int i = indexLine+1; i < TxtForm->TDMemo->Lines->Count; i++ )
        for ( int i = 1; i < TxtForm->Memo1->Lines->Count; i++ )
        { //
//          strcpy( buf, TxtForm->TDMemo->Lines->Strings[ i ].c_str( ) );
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i ].c_str( ) );
          sLen = strlen( buf );
          // Conversion Loop
          for ( int c = 0; c < sLen; c++ )
          { //-------------------------//
            // Check for control codes //
            //-------------------------//
            if ( buf[ c ] == '[' )
            { // Get to the code
              c++;
              c_test = 0;
              flag   = 0;
              while( codes[ c_test ][ 0 ] )
              { // Do some comparisons
                if ( !strncmpi( &buf[c], codes[ c_test ], strlen( codes[ c_test ] )) &&
                     buf[ c + strlen( codes[ c_test ] ) ] == ']'
                   )
                { // Advance Testing Data's curent position
                  c += strlen( codes[ c_test ] );
                  // Store the control code
                  EStr[ inPosi++ ] = 0;
                  EStr[ inPosi++ ] = codes[ c_test + 1 ][0];
                  // If this is true, do NOT set the flag!
                  if ( buf[ c ] == '$' ) break;
                  // We found what we need! No more test
                  flag = 1;
                  // Decrementc since it's part of a FOR loop
                  break;
                } // END IF
                //
                c_test += 2;
              }

              // If FLAG still zero, no code match was found!
              if ( !flag )
              { // Check for HEX Only codes
                if ( buf[c] == '$')
                { //
                  c++;
                  while( (c < sLen) && buf[c] != ']' ){
                    memcpy( conv, &buf[c], 2 ); conv[ 2 ] = 0;
                    EStr[ inPosi++ ] = strtol( conv, NULL, 16 );
                    c += 2;
                  }

                  //
                  EStr[ inPosi ] = STRING_END;
                }
                else
                { // If it comes here then it's regular data
                  EStr[ inPosi++ ] = buf[ --c ];
                  EStr[ inPosi   ] = STRING_END;
                }
              } // END IF

            } // END IF - Control Codes
            else
            { // regular text
              EStr[ inPosi++ ] = buf[ c ];
              EStr[ inPosi   ] = STRING_END;
            } // END IF - Everything else
          }

          // Add the Line Break if needed
//          strcpy( buf, TxtForm->TDMemo->Lines->Strings[ i + 1 ].c_str( ) );
          strcpy( buf, TxtForm->Memo1->Lines->Strings[ i + 1 ].c_str( ) );
          if ( !strncmpi( buf, ".ENDS", 5) ){
            EStr[ inPosi++ ] = TEXT_BREAK & 0xFF;
            EStr[ inPosi++ ] = TEXT_BREAK >> 8;
            EStr[ inPosi   ] = STRING_END;
            break;
          } else {
            EStr[ inPosi++ ] = LINE_BREAK & 0xFF;
            EStr[ inPosi++ ] = LINE_BREAK >> 8;
            EStr[ inPosi   ] = STRING_END;
          }
        } // NEXT i

        //
        DTT->Checked = true;
        DrawText( false, 16, 16 );
        DTT->Checked = false;
      }

      //
/*
      sprintf( buf, "Offset: %06X | PTR: %04X -> %06X",
                    0x7E0000 | txt.pntr,
                    txt.pntr,
                    0x7E0000 | ((txt.ptr_index << 6) + 0x0E)
             );
*/
      sprintf( buf, "Offset: %06X | PTR: %04X -> %06X",
                    0,
                    txt.pntr,
                    0
             );

      //
      StatusBar1->Panels->Items[0]->Text = AnsiString( buf );
      StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
      if ( Sender && (LONG)Sender != 1 && cmForm->Visible ) cmForm->pList->SetFocus( );
      break;
    }
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::Find1Find(TObject *Sender)
{
/*  int  StartPos,
       ToEnd,
       curLine,
       indexLine;
*/
  // begin the search after the current selection
  // if there is one
  // otherwise, begin at the start of the text
  if ( TxtForm->TDMemo->SelLength )
    StartPos = TxtForm->TDMemo->SelStart + TxtForm->TDMemo->SelLength;
  else

    StartPos = 0;

  // ToEnd is the length from StartPos
  // to the end of the text in the rich edit control

  ToEnd   = TxtForm->TDMemo->Text.Length( ) - StartPos;

  FoundAt = TxtForm->TDMemo->FindText( Find1->FindText, StartPos, ToEnd, TSearchTypes( ) );
  //

  if ( FoundAt != -1 )
  {
//    if ( TxtForm->Visible ) TxtForm->TDMemo->SetFocus( );
    TxtForm->TDMemo->SelStart  = FoundAt;
    TxtForm->TDMemo->SelLength = 0;
    //
    curLine              = TxtForm->TDMemo->Perform( EM_GETFIRSTVISIBLELINE, 0, 0 );
    if ( TxtForm->TDMemo->Text.Length( ) > 0xFFFF )
      indexLine          = TxtForm->TDMemo->Perform( EM_EXLINEFROMCHAR, FoundAt, 0 );
    else
      indexLine          = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, FoundAt, 0 );
    //
    if ( (LONG)Sender != 1 )
      TxtForm->TDMemo->Perform( EM_LINESCROLL, 0, indexLine - curLine );
  }
  else
  {
    indexLine = -1;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
long __fastcall TmyForm::GetCurLine( long valu )
{
  DWORD both = 0;
  int indexLine;
  int indexLength;

  both        = MAKELPARAM( (valu >> 16) & 0xFFFF, (valu >> 0 ) & 0xFFFF );
  indexLine   = TxtForm->TDMemo->Perform( EM_LINEFROMCHAR, -1, 0 );
  indexLength = (LOWORD(both)/8) + TxtForm->TDMemo->SelLength;

  return indexLine;
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayTextEditor1Click(TObject *Sender)
{
//  TxtForm->Left = espkForm->Left;
//  TxtForm->Top  = espkForm->Top;
  TxtForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::HideCodesClick(TObject *Sender)
{
  HideCodes->Checked ^= 1;
  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;

/*  char *str[4] = { "Visible", "Hidden", "Inactive", "Active" };
  //
  HideCodes->Checked ^= 1;
  DrawText( false, map.height, map.width );
  //
  StatusBar1->Panels->Items[1]->Text = "Control Codes: " + AnsiString( str[ HideCodes->Checked & 1 ] ) + " | VWF: " + AnsiString( str[ (UseVWFRoutine1->Checked & 1) + 2 ] );
*/
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::UseVWFRoutine1Click(TObject *Sender)
{
  UseVWFRoutine1->Checked ^= 1;
  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;

/*  char *str[4] = { "Visible", "Hidden", "Inactive", "Active" };
  //
  UseVWFRoutine1->Checked ^= 1;
  DrawText( false, map.height, map.width );
  //
  StatusBar1->Panels->Items[1]->Text = "Control Codes: " + AnsiString( str[ HideCodes->Checked & 1 ] ) + " | VWF: " + AnsiString( str[ (UseVWFRoutine1->Checked & 1) + 2 ] );
*/
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DTTClick(TObject *Sender)
{
  DTT->Checked ^= true;
  //
//  if ( DTT->Checked )
  pListClick( Sender );
}

//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Red1Click(TObject *Sender)
{
  TMenuItem *m = (TMenuItem *)Sender;

  m->Checked = true;

  // Kana
  DTT->Checked = false;
  DrawText( false, map.height, map.width );
  // Ascii
  DTT->Checked = true;
  DrawText( false, map.height, map.width );
  DTT->Checked = false;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::Zoominx21Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY + 256;
  myForm->ClientWidth  = WinX << 1;
  //
  FormResize( NULL );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DefaultWindowSize1Click(TObject *Sender)
{
  if ( myForm->WindowState == wsMaximized )
    myForm->WindowState = wsNormal;
  //
  myForm->ClientHeight = WinY;
  myForm->ClientWidth  = WinX;
  //
  FormResize( myForm );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::DisplayKanaTextDump1Click(TObject *Sender)
{
  KanaForm->Show( );
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormResize(TObject *Sender)
{
  //
  if ( isActive == false ) return;
  //
  if ( myForm->WindowState == wsNormal )
  {
    TxtForm->Top  = myForm->Top;
    TxtForm->Left = myForm->Left + myForm->Width + 2;
    //
    cmForm->Top  = TxtForm->Top + TxtForm->Height + 2;;
    cmForm->Left = TxtForm->Left;
    //
    if ( Sender != NULL )
    {
      KanaForm->Left = myForm->Left;
      KanaForm->Top  = myForm->Top + myForm->Height + 2;
    }
    else
    {
      KanaForm->Left = cmForm->Left;
      KanaForm->Top  = cmForm->Top + cmForm->Height + 2;
    }
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::TEOnTopClick(TObject *Sender)
{
  TEOnTop->Checked ^= true;
  //
  if ( TEOnTop->Checked )
  {
    TxtForm->FormStyle = fsStayOnTop;
    KanaForm->FormStyle = fsStayOnTop;
  }
  else
  {
    TxtForm->FormStyle = fsNormal;
    KanaForm->FormStyle = fsNormal;
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::ViewHexData1Click(TObject *Sender)
{
  HexForm->Show( );
}


//--------------------------//
// Decompression Subroutine //
//--------------------------//
long __fastcall TmyForm::Decompress( LONG lpOffset )
{
  LONG offset;

  return offset;
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DecompresstoFiles1Click(TObject *Sender)
{
  cmForm->Show( );
}


//------------------------//
//                        //
//------------------------//
void __fastcall TmyForm::DumpMemory1Click(TObject *Sender)
{
  FILE *sf;

  FSave->InitialDir = cur_dir;
  FSave->Title      = "Dump Working RAM to file...";

  if ( FSave->Execute( ) )
  { //
    sf = fopen( FSave->FileName.c_str( ), "wb" );
    if ( !sf ){
      ShowMessage( "Error: Could not open file for saving..." );
      return;
    }
    //
    fwrite( ram, 1, 0x20000, sf );
    fclose( sf );
  }
}


//---------------------------------//
//                                 //
//---------------------------------//
void __fastcall TmyForm::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
  TBOX *myBox = NULL;

  if ( Shift.Contains( ssShift) ) myBox = &textbox[0];
  if ( Shift.Contains( ssCtrl ) ) myBox = &textbox[1];

  if ( myBox )
  {
    switch( Key )
    {
      case VK_UP  : if ( myBox->Ypos ) myBox->Ypos -= 16; else Key = 0; break;
      case VK_DOWN: if ( (myBox->Ypos + 96) < 0x300 ) myBox->Ypos += 16; else Key = 0; break;
      default     : Key = 0; break;
    }
  }

  // Kana
  if ( Key )
  {
    DTT->Checked = false;
    DrawText( false, map.height, map.width);

    // Ascii
    DTT->Checked = true;
    DrawText( false, map.height, map.width );
    DTT->Checked = false;
    //
//    StatusBar1->Panels->Items[1]->Text = "Kana line: " + IntToStr( (textbox[0].Ypos >> 4) ) + " | ASCII line: " + IntToStr( (textbox[1].Ypos >> 4) );
    StatusBar1->Panels->Items[1]->Text = "Line {Kana, Ascii}: " + IntToStr( (textbox[0].Ypos >> 4) ) + ", " + IntToStr( (textbox[1].Ypos >> 4) );
  }
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::SaveRomFile1Click(TObject *Sender)
{
  FILE *rf = NULL;

  if ( !rom.data || !ram ) return;
  //
  rf = fopen( romf, "wb" );
  if ( !rf )
  { //
    ShowMessage( "Fatal Error: Could not open ROM File for saving..." );
    return;
  }
  //
  fwrite( (rom.data - rom.Header), 1, rom.Length, rf );
  fclose( rf );
  //
  if ( isActive )
    ShowMessage( "ROM File saved successfully!" );
  //
  rom.Modified = false;
}


//------------------------------------//
//                                    //
//------------------------------------//
void __fastcall TmyForm::EditorKeys1Click(TObject *Sender)
{
  ShowMessage(
    "Shift + UP  : Scroll the KANA Textbox Data Up by 'ONE line'.\n"
    "Shift + DOWN: Scroll the KANA Textbox Data Down by 'ONE line'.\n"
    "Ctrl  + UP  : Scroll the ASCII Textbox Data Up by 'ONE line'.\n"
    "Ctrl  + DOWN: Scroll the ASCII Textbox Data Down by 'ONE line'.\n"
  );
}


//------------------------------------//
//                                    //
//------------------------------------//
long __fastcall TmyForm::GetTextPointers( LONG lpCurPosi )
{
  LONG lpOffset = lpCurPosi,
       value    = 0;
  WORD index    = 0,
       previous = 0;
  WORD count    = 0;

  while( index != 0x0059 && lpOffset < (rom.Length - rom.Header))
  {
    index     = WGET( rom.data, lpOffset );
    lpOffset += 2;
    //
    switch( index )
    {
      case 0xFFFF : break; //return count;                // End of script
      case 0x0000 : break;     // No args   ; Reset game
      case 0x0001 : break;     // No args
      case 0x0002 : break;     // No args
      case 0x0003 : break;     // No args
      case 0x0004 : lpOffset += 2; break;     // 2 BYTES
      case 0x0005 : break;     // No args
      case 0x0006 : break;     // No args   ; Clear Textmap Buffer?
      case 0x0007 : break;     // No args
      case 0x0008 : break;     // No args
      case 0x0009 : break;     // No args
      case 0x000A : break;     // No args
      case 0x000B : break;     // No args
      case 0x000C : lpOffset += 2; break;     // 2 BYTES
      case 0x000D : lpOffset += 2; break;     // 2 BYTES
      case 0x000E : break;     // No args   ; Fadein??
      case 0x000F : break;     // No args   ; Fadeout??
      case 0x0010 : break;     // No args
      case 0x0011 : break;     // No args
      case 0x0012 : break;     // BYTES
      case 0x0013 : break;     // 1 BYTE
      case 0x0014 : lpOffset += 1; break;     // 1 BYTE
      case 0x0015 : break;     // No args
      case 0x0016 : lpOffset += 1; break;     // 1 BYTE    ; screen flashed white
      case 0x0017 : lpOffset += 1; break;     // 1 BYTE
      case 0x0018 : lpOffset += 1; break;     // 1 BYTE
      case 0x0019 : lpOffset += 1; break;     // 1 BYTE
      case 0x001A : break;     // No args
      case 0x001B : break;     // No args
      case 0x001C : break;     // No args
      case 0x001D : break;     // No args
      case 0x001E : lpOffset += 2; break;     // 2 BYTES
      case 0x001F : lpOffset += 4; break;     // 4 BYTES
      case 0x0020 : lpOffset += 4; break;     // 4 BYTES
      case 0x0021 : lpOffset += 1; break;     // 1 BYTE
      case 0x0022 : lpOffset += 1; break;     // 1 BYTE
      case 0x0023 : break;     // No args   ; Scroll screen?
      case 0x0024 : lpOffset += 2; break;     // 2 BYTES
      case 0x0025 : lpOffset += 2; break;     // 2 BYTES
//---------------- THIS AREA NEEDS WORK ----------------
      case 0x0026 : lpOffset = lpOffset; //lpOffset += 2; break;     // Varies, Could be a "control statement" code
      case 0x0027 : lpOffset++;  // garunteed 1 BYTE
                    while( rom.data[ lpOffset ] != 0xFF && lpOffset < (rom.Length - rom.Header))
                      lpOffset++;
                    //
                    lpOffset += 2; break;     // Varies, Could be a "control statement" code
//---------------- THIS AREA NEEDS WORK ----------------
      case 0x0028 : lpOffset += 3; break;     // 3 BYTES
      case 0x0029 : lpOffset += 3; break;     // 3 BYTES
      case 0x002A : lpOffset += 2; break;     // 2 BYTES
      case 0x002B : lpOffset += 2; break;     // 2 BYTES
      case 0x002C : lpOffset += 1; break;     // 1 BYTE
      case 0x002D : lpOffset += 1; break;     // 1 BYTE
      case 0x002E : break;     // No args
      case 0x002F : break;     // No args
      case 0x0030 : break;     // No args
      case 0x0031 : break;     // No args
      case 0x0032 : lpOffset += 1; break;     // 1 BYTE
      case 0x0033 : lpOffset += 1; break;     // 1 BYTE
      case 0x0034 : break;     // No args
      case 0x0035 : break;     // No args
      case 0x0036 : break;     // No args
      case 0x0037 : break;     // No args
      case 0x0038 : break;     // No args
      case 0x0039 : break;     // No args
      case 0x003A : break;     // No args
      case 0x003B : break;     // No args
      // Text Pointers, Upper Textbox
      case 0x003C : value = LGET( rom.data, lpOffset ) & 0x00FFFFFF;
                    if ( value < 0xC00000 ){ lpOffset += 2; break; }
                    //--------------------------------------
                    lpTxtPoints[ count++ ] = Snes2Pc( value );
                    lpOffset += 3;
                    break;     // 3 BYTES     ; Upper Textbox?? @ 24-bit Text pointer
      // Text Pointers, Lower Textbox
      case 0x003D : value = LGET( rom.data, lpOffset ) & 0x00FFFFFF;
                    if ( value < 0xC00000 ){ lpOffset += 2; break; }
                    //--------------------------------------
                    lpTxtPoints[ count++ ] = Snes2Pc( value );
                    lpOffset += 3;
                    break;     // 3 BYTES     ; Lower Textbox?? @ 24-bit Text pointer
      case 0x003E : break;     // No args
      case 0x003F : break;     // No args
      case 0x0040 : break;     // No args
      // Text Pointers, Center Textbox
      case 0x0041 : value = LGET( rom.data, lpOffset ) & 0x00FFFFFF;
                    if ( value < 0xC00000 ){ lpOffset += 2; break; }
                    //--------------------------------------
                    lpTxtPoints[ count++ ] = Snes2Pc( value );
                    lpOffset += 3;
                    break;     // 3 BYTES     ; Center Textbox?? @ 24-bit Text pointer
      // Unknown Pointer, record for now
      case 0x0042 : value = LGET( rom.data, lpOffset ) & 0x00FFFFFF;
                    if ( value < 0xC00000 ){ lpOffset += 2; break; }
                    //--------------------------------------
//                    lpTxtPoints[ count++ ] = Snes2Pc( value );
                    lpOffset += 3;
                    break;     // 3 BYTES     ; unknown?? @ 24-bit pointer
      case 0x0043 : lpOffset += 1; break;     // 1 BYTE
      case 0x0044 : lpOffset += 1; break;     // 1 BYTE
      case 0x0045 : break;     // No args
      case 0x0046 : break;     // No args
      case 0x0047 : break;     // No args
      case 0x0048 : lpOffset += 4; break;     // 4 BYTES
      case 0x0049 : lpOffset += 4; break;     // 4 BYTES
      case 0x004A : lpOffset += 4; break;     // 4 BYTES     ; 1 BYTE, 3 Script Call Offset
      case 0x004B : lpOffset += 4; break;     // 4 BYTES     ; 1 BYTE, 3 Script Call Offset
      case 0x004C : lpOffset += 4; break;     // 4 BYTES
      case 0x004D : lpOffset += 4; break;     // 4 BYTES     ; 1 BYTE, 3 Script Call Offset
//---------------- THIS AREA NEEDS WORK ----------------
      case 0x004E : lpOffset += 7; break;     // Varies, Could be a "control statement" code
      case 0x004F : lpOffset += 7; break;     // Varies, Could be a "control statement" code
      case 0x0050 : lpOffset += 9; break;     // Varies, Could be a "control statement" code
      case 0x0051 : lpOffset += 9; break;     // Varies, Could be a "control statement" code
      case 0x0052 : lpOffset += 5; break;     // Varies, Could be a "control statement" code
      case 0x0053 : lpOffset += 5; break;     // Varies, Could be a "control statement" code
//---------------- THIS AREA NEEDS WORK ----------------
      case 0x0054 : lpOffset += 3; break;     // 3 BYTES
      case 0x0055 : lpOffset += 1; break;     // 1 BYTE
      case 0x0056 : lpOffset += 1; break;     // 1 BYTE
      case 0x0057 : lpOffset += 4; break;     // 4 BYTES
      case 0x0058 : lpOffset += 4; break;     // 4 BYTES
      case 0x0059 : return count;             // No args   ; End of script block, followed by $FFFF
      default     : return count;
    }
    //
    previous = index;
  }

  return -1;
}



/*
/*        if( rom.data[ lpOfset ] != 0xFF )
        { //
          lpOffset++;
          //
          if( rom.data[ lpOfset ] != 0xFF )
          { //
            lpOffset++;
            //
            if( rom.data[ lpOfset ] != 0xFF )
            {

            }
            else
            {

            }  // $FF, $FF, $FF, $xx
          }
          else
            lpOffset += 6;
          // $FF, $FF, $xx
        }
        else
          lpOffset += 7;
        // $FF, $xx
      }
*/

